package com.wk.hooker.hooks;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.TextView;

import com.wk.hooker.util.AppUtils;

import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;

import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XSharedPreferences;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;


public class MainHook implements IXposedHookLoadPackage {

    private byte[] buffer;
    private final static String issaomaopen = "IS_SAOMAOPEN";
    private final static String saomatime = "SAOMA_TIME";
    private final static String qr = "QR";
    private final static String moniqr = "MoNI_QR";
    private final static String loginstate="login_state"; //0已经上线 ，1 判断是否已经上线状态，2掉线
    private Activity basescaner;
    private Activity deviceweblogin;
    private boolean run = false;


    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam paramLoadPackageParam)
            throws Throwable {
        if (!paramLoadPackageParam.packageName.equals("com.tencent.mm"))
            return;

        registrationQrcode(paramLoadPackageParam);

    }

    private boolean isInit = false;











    /**
     * **********
     * 注册二维码的监听
     *
     * @param paramLoadPackageParam
     * @throws Throwable
     */
    private void registrationQrcode(XC_LoadPackage.LoadPackageParam paramLoadPackageParam) throws Throwable {

        //第一步监听主界面的Activity的onResume()
        Class clazz = XposedHelpers.findClass("com.tencent.mm.ui.LauncherUI",
                paramLoadPackageParam.classLoader);
        Method loadUrl1 = clazz.getDeclaredMethod("onResume");
        XC_MethodHook xc_methodHook = new XC_MethodHook() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                super.beforeHookedMethod(param);
                Class classType = param.thisObject.getClass();
                final XSharedPreferences xSharedPreferences = new XSharedPreferences("com.wk.hooker.login","weixinok");
                int clearmsgtemp = xSharedPreferences.getInt("clear_msg",0);

                if(clearmsgtemp==1){
                    if(clearMsg())
                       return;
                }

                if (!isInit) {
                    hookConitune(param.thisObject.getClass().getClassLoader());
                    isInit = true;
                }
            }

            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                super.afterHookedMethod(param);
                startBaseScanUI(param);
            }
        };

        XposedBridge.hookMethod(loadUrl1, xc_methodHook);


    }


    private TextView login;


    private void hookConitune(ClassLoader clsLoader) {
        //注册处理二维码的监听后修改二维码得到的二维码的数据
        Class clazza = XposedHelpers.findClass("c.a",
                clsLoader);
        XposedHelpers.findAndHookMethod(
                "com.tencent.mm.plugin.scanner.b.c",
                clsLoader, "asx", new XC_MethodHook() {
                    @Override
                    protected void beforeHookedMethod(MethodHookParam param)
                            throws Throwable {
                        super.beforeHookedMethod(param);
                    }

                    @Override
                    protected void afterHookedMethod(MethodHookParam param)
                            throws Throwable {
                        super.afterHookedMethod(param);
                        XposedBridge.log("扫描结束修改扫描的二维码结果");
                        modifyQrResults(param);
                    }
                });

        XposedHelpers.findAndHookMethod(
                "com.tencent.mm.plugin.scanner.ui.BaseScanUI",
                clsLoader, "onDestroy", new XC_MethodHook() {
                    @Override
                    protected void beforeHookedMethod(MethodHookParam param)
                            throws Throwable {
                        super.beforeHookedMethod(param);
                    }

                    @Override
                    protected void afterHookedMethod(MethodHookParam param)
                            throws Throwable {
                        super.afterHookedMethod(param);
                        basescaner = null;

                    }
                });
        //注册找到点击登录的按钮
        XposedHelpers.findAndHookMethod(
                "android.widget.HeaderViewListAdapter",
                clsLoader, "getView", int.class, View.class, ViewGroup.class, new XC_MethodHook() {
                    @Override
                    protected void beforeHookedMethod(MethodHookParam param)
                            throws Throwable {
                        super.beforeHookedMethod(param);
                    }

                    @Override
                    protected void afterHookedMethod(MethodHookParam param)
                            throws Throwable {
                        super.afterHookedMethod(param);
                        performautouWebLogin(param);
                    }
                });
        atuoWebLogin(clsLoader);
    }


    /**
     * ******
     * 自动登录网页版微信
     *
     * @param clsLoader 类加载器
     */
    private void atuoWebLogin(ClassLoader clsLoader) {
        Class clazza = XposedHelpers.findClass("com.tencent.mm.plugin.scanner.ui.BaseScanUI",
                clsLoader);
        findNoinheritanceMethod(clazza, "onResume", new XC_MethodHook() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                super.beforeHookedMethod(param);

            }
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                super.afterHookedMethod(param);
                basescaner= (Activity) param.thisObject;
                final XSharedPreferences xSharedPreferences = new XSharedPreferences("com.wk.hooker.login","weixinok");
                int state = xSharedPreferences.getInt(loginstate,1);
                if(!xSharedPreferences.getBoolean(issaomaopen,true)){

                    return;
                }
                if(!xSharedPreferences.getBoolean(issaomaopen,true)||state==2){//或者已经上线
                    basescaner.onBackPressed();
                    return;
                }
                Class basescanuiclass = basescaner.getClass();
                Method method = basescanuiclass.getDeclaredMethod("onActivityResult",int.class,int.class,Intent.class);
                method.setAccessible(true);
                Intent intent = new Intent();
                File file = new File(Environment.getExternalStorageDirectory(), "qr.jpg");
                if(!file.exists()){
                    basescaner.onBackPressed();
                }else{
                    Uri uri =Uri.parse(file.getAbsolutePath());
                    intent.setData(uri);
                    method.invoke(basescaner,4660,-1,intent);
                }
                //微信被封号摄像头调用过久关闭
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(20 * 1000);
                            if(basescaner!=null)
                                basescaner.runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    try {
                                        basescaner.onBackPressed();
                                        basescaner = null;
                                    } catch (Exception e) {

                                    }
                                }
                            });

                        } catch (Exception e) {

                        }
                    }
                }).start();

            }

        });

        Class clazza2 = XposedHelpers.findClass("com.tencent.mm.plugin.webwx.ui.ExtDeviceWXLoginUI",
                clsLoader);
        findNoinheritanceMethod(clazza2, "onCreate",new XC_MethodHook() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                super.beforeHookedMethod(param);

            }
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                super.afterHookedMethod(param);

                deviceweblogin= (Activity) param.thisObject;
                String s = deviceweblogin.getIntent().getStringExtra("intent.key.login.url");
                XposedBridge.log("方法找到执行结束:::"+s);
                int s2  = deviceweblogin.getIntent().getIntExtra("intent.key.type", 0);
                XposedBridge.log("方法找到执行结束:::"+s2);
                String s3 = deviceweblogin.getIntent().getStringExtra("intent.key.title.string");
                XposedBridge.log("方法找到执行结束:::"+s3);
                int i = deviceweblogin.getIntent().getIntExtra("intent.key.icon.type", 0);
                XposedBridge.log("方法找到执行结束:::"+i);
                String localObject1 = deviceweblogin.getIntent().getStringExtra("intent.key.ok.string");
                XposedBridge.log("方法找到执行结束:::"+localObject1);
                String str1 = deviceweblogin.getIntent().getStringExtra("intent.key.cancel.string");
                XposedBridge.log("方法找到执行结束:::"+str1);
                String str2 = deviceweblogin.getIntent().getStringExtra("intent.key.content.string");
                XposedBridge.log("方法找到执行结束:::"+str2);
                String s4 = deviceweblogin.getIntent().getStringExtra("intent.key.ok.session.list");
                XposedBridge.log("方法找到执行结束:::"+s4);
                if(str1==null){
                    XposedBridge.log("网页登录的页面无法登录：推出");
                    deviceweblogin.onBackPressed();
                    if(basescaner!=null){
                        basescaner.onBackPressed();
                    }
                }

            }
        },Bundle.class);


        findNoinheritanceMethod(clazza2, "onDestroy",new XC_MethodHook() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                super.beforeHookedMethod(param);

            }
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                super.afterHookedMethod(param);
                XposedBridge.log("网页微信登录的页面被销毁");
                deviceweblogin=null;
            }
        });



    }
    /**
     * ****
     * 启动扫描的二维码的界面
     *
     * @param param
     */
    private void startBaseScanUI(XC_MethodHook.MethodHookParam param)throws Throwable {
        final Activity activity = (Activity) param.thisObject;
        final XSharedPreferences xSharedPreferences = new XSharedPreferences("com.wk.hooker.login","weixinok");
        int state = xSharedPreferences.getInt(loginstate,1);


        if(!xSharedPreferences.getBoolean(issaomaopen,true)||state==2){//或者已经上线
            return;
        }
        if(deviceweblogin!=null){
            deviceweblogin.finish();
            deviceweblogin =null;
            activity.onBackPressed();
            return ;
        }
        if(basescaner!=null){
            activity.onBackPressed();
            return;
        }
        if(run){
            return;
        }

        int temp = 40;
        try{
           String times =xSharedPreferences.getString(saomatime,40+"");
            temp = Integer.valueOf(times);

        }catch (Exception e){
            e.printStackTrace();
        }
       final  int tiem = temp;
        //延迟启动扫描二维码的界面参数配置
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    run=true;
                    Thread.sleep(tiem * 1000);
                    activity.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                run = false;
                                if(!xSharedPreferences.getBoolean(issaomaopen,true)){
                                    return;
                                }
                                Date now = new Date();
                                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
                                XposedBridge.log("微信启动后开始启动摄像头扫描》》》"+dateFormat.format(now));
                                Class cass = activity.getClassLoader().loadClass("com.tencent.mm.plugin.scanner.ui.BaseScanUI");
                                Intent intent = new Intent(activity, cass);
                                activity.startActivity(intent);
                                activity.onBackPressed();
                            } catch (Exception e) {

                            }
                        }
                    });

                } catch (Exception e) {

                }
            }
        }).start();
    }

    /*********
     * 执行扫码成功后自动登录
     * @param param
     */
    private void performautouWebLogin(XC_MethodHook.MethodHookParam param)throws Throwable{
        final XSharedPreferences xSharedPreferences = new XSharedPreferences("com.wk.hooker.login","weixinok");
        if(!xSharedPreferences.getBoolean(issaomaopen,true)){
            return;
        }

        View view = (View) param.getResult();
        Activity activity = (Activity) view.getContext();
        Class c = activity.getClass();
        if(!c.getName().equals("com.tencent.mm.plugin.webwx.ui.ExtDeviceWXLoginUI")){
            return;
        }
        if ((param.args[0] + "").equals("2")) {//找到登录的view
            final ViewGroup viewgroup = (ViewGroup) view;
            if(viewgroup.getChildAt(0) instanceof  TextView){
                login = (TextView) viewgroup.getChildAt(0);
            }
        }
        if ((param.args[0] + "").equals("4")) {

            if(!c.getName().equals("com.tencent.mm.plugin.webwx.ui.ExtDeviceWXLoginUI")){
                return;
            }
            XposedBridge.log("开始执行自动登录>>"+param.args[0]+c.getName());
            Field field = c.getField("gUa");
            field.setAccessible(true);
            ListView listView = (ListView) field.get(activity);
            listView.performItemClick(login, 2, listView.getItemIdAtPosition(2));
        }
    }


    /*********
     * 清除微信消息记录
     */
    private boolean clearMsg(){

        //0e7cbebb5ae67e9e2183f7b9399ff613
        File file;
        XSharedPreferences xSharedPreferences = new XSharedPreferences("com.wk.hooker.login","weixinok");
        String str=xSharedPreferences.getString("filename","");
        if(str.equals("")){

            return  false;
        }
        file = new File("/data/data/com.tencent.mm/MicroMsg/"+str+"/EnMicroMsg.db");
        if(file.delete()){
            //删除后备份一份文件
            AppUtils.pushFile(Environment.getExternalStorageDirectory().getPath()+"/EnMicroMsg.db","/data/data/com.tencent.mm/MicroMsg/"+str+"/EnMicroMsg.db");
            //关闭微信进程
            android.os.Process.killProcess(android.os.Process.myPid());
            return  true;
        }

        return  false;

    }



    /********
     * 扫描结束后修改二维码的结果
     * @param param
     * @throws Throwable
     */
    private void modifyQrResults(XC_MethodHook.MethodHookParam param)throws Throwable{
        XSharedPreferences xSharedPreferences = new XSharedPreferences("com.wk.hooker.login","weixinok");
        if(!xSharedPreferences.getBoolean(issaomaopen,true)){
            return;
        }
        Field field = param.thisObject.getClass().getField("gbH");
        field.setAccessible(true);
        field.set(param.thisObject, xSharedPreferences.getString("QR","https://login.weixin.qq.com/l/wY-6rtnKFA=="));
    }






    /**
     * **
     * 用递归的方法找到子类没有实现的方法
     *
     * @param hook
     * @param clazz
     * @param methodName
     * @param param
     */
    private void findNoinheritanceMethod(Class clazz, String methodName, XC_MethodHook hook, Class<?>... param) {

        if (clazz.getName().equals("java.lang.Object")) {
            XposedBridge.log("测底没有找到相关方法~");
            return;
        }
        try {
            Method   method = clazz.getDeclaredMethod(methodName,param);
            XposedBridge.hookMethod(method, hook);
            return;
        } catch (java.lang.NoSuchMethodException e) {
            XposedBridge.log("没有找到相关方法~" + clazz.getName());
            findNoinheritanceMethod(clazz.getSuperclass(), methodName, hook, param);
        }
    }
}
